﻿using System;
using System.Collections.Generic;
using System.Linq;
using Coolite.Ext.Web;
using Pap.Core.Utilities;
using Pap.Data;
using Pap.Web.Modules.Shared.ViewModel;
using Pap.Web.Utils;

namespace Pap.Web.Modules.Shared.Views
{
    /// <summary>
    /// 
    /// </summary>
    public partial class InsertAttchments : BaseUserControl<InsertAttachmentsViewModel>
    {
        #region [ helpers ]
        /// <summary>
        /// Gets the images.
        /// </summary>
        private IList<IImage> Images
        {
            get
            {
                if (!RegistryInfo.Images.ContainsKey(this.ClientID))
                {
                    var images = new List<IImage>();
                    RegistryInfo.Images[this.ClientID] = new List<IImage>();
                }

                return RegistryInfo.Images[this.ClientID];
            }
        }
        /// <summary>
        /// Gets or sets the deleted images.
        /// </summary>
        /// <value>
        /// The deleted images.
        /// </value>
        private IList<Guid> DeletedImages
        {
            get
            {
                var deletedImageIds = this.ViewState["DeletedImages"] as IList<Guid>;
                if (deletedImageIds == null)
                {
                    deletedImageIds = new List<Guid>();
                    this.ViewState["DeletedImages"] = deletedImageIds;
                }
                return deletedImageIds;
            }
            set
            {
                if (value == null)
                {
                    this.ViewState.Remove("DeletedImages");
                }
                else
                    this.ViewState["DeletedImages"] = value;
            }
        }
        /// <summary>
        /// Refreshes the images.
        /// </summary>
        private void RefreshImages()
        {
            this.sImages.DataSource = this.Images;
            this.sImages.DataBind();
        }
        /// <summary>
        /// Clears the fields.
        /// </summary>
        private void ClearFields()
        {
            fuImage.Reset();
            txtPhotoLabels.Reset();
            cmbType.Reset();
        }

        /// <summary>
        /// Gets or sets the editable image id.
        /// </summary>
        /// <value>
        /// The editable image id.
        /// </value>
        private Guid? EditableImageId
        {
            set
            {
                this.ViewState["EditableImageId"] = value;
            }
            get
            {
                var obj = this.ViewState["EditableImageId"];
                if (obj == null)
                    return null;
                return (Guid)obj;
            }
        }
        #endregion

        #region [ Events ]

        /// <summary>
        /// Handles the Load event of the Page control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack && !Ext.IsAjaxRequest)
            {
                sImageTypes.DataSource = this.ViewModel.GetImageTypes();
                sImageTypes.DataBind();
            }
        }
        /// <summary>
        /// Raises the <see cref="E:System.Web.UI.Control.Init"/> event.
        /// </summary>
        /// <param name="e">An <see cref="T:System.EventArgs"/> object that contains the event data.</param>
        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            if (!IsPostBack && !Ext.IsAjaxRequest)
                RegistryInfo.Images.Remove(this.ClientID);
        }

        /// <summary>
        /// Handles the Click event of the btnUpload control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="Coolite.Ext.Web.AjaxEventArgs"/> instance containing the event data.</param>
        protected void BtnUploadClick(object sender, AjaxEventArgs e)
        {
            if (this.EditableImageId.HasValue)
            {
                var image = this.Images.Single(i => i.ImageID == this.EditableImageId.Value);
                image.ImageTypeID = cmbType.SelectedItem.Value.ToGuid();
                image.Label = this.txtPhotoLabels.Text;

                this.EditableImageId = null;
                this.fuImage.Disabled = false;
            }
            else if (this.fuImage.HasFile)
            {
                this.Images.AddImage(fuImage.FileBytes, this.txtPhotoLabels.Text,
                                             this.cmbType.SelectedItem.Value.ToGuid());
                RefreshImages();
            }

            ClearFields();
        }

        /// <summary>
        /// Handles the Click event of the btnDelete control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="Coolite.Ext.Web.AjaxEventArgs"/> instance containing the event data.</param>
        protected void BtnDeleteClick(object sender, AjaxEventArgs e)
        {
            var imageId = e.ExtraParams["ImageId"].Trim('"').ToGuid();
            this.DeletedImages.Add(imageId);
            this.Images.Remove(this.Images.Single(i => i.ImageID == imageId));
            RefreshImages();
            ClearFields();
        }

        /// <summary>
        /// Dvs the image selection change.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="Coolite.Ext.Web.AjaxEventArgs"/> instance containing the event data.</param>
        protected void DvImageSelectionChange(object sender, AjaxEventArgs e)
        {
            var imageId = e.ExtraParams["ImageId"].Trim('"').ToGuid();
            var image = this.Images.Single(i => i.ImageID == imageId);
            //----------------------------------------------------------------
            EditableImageId = imageId;
            cmbType.SetValue(image.ImageTypeID);
            txtPhotoLabels.Text = image.Label;
            this.fuImage.Disabled = true;
        }

        #endregion

        #region [ Interface ]

        /// <summary>
        /// Sets the images.
        /// </summary>
        /// <param name="images">The images.</param>
        public void SetImages(IEnumerable<IImage> images)
        {
            ((List<IImage>)this.Images).AddRange(images);
            RefreshImages();
            ClearFields();
        }

        /// <summary>
        /// Gets the inserted I ds.
        /// </summary>
        /// <returns></returns>
        public IEnumerable<Guid> GetInsertedIDs()
        {
            return this.Images.OfType<InMemoryImage>().Select(i => i.ImageID);
        }

        /// <summary>
        /// Gets the deleted I ds.
        /// </summary>
        /// <returns></returns>
        public IEnumerable<Guid> GetDeletedIDs()
        {
            return this.DeletedImages;
        }

        /// <summary>
        /// Saves this instance.
        /// </summary>
        public void Save()
        {
            try
            {
                this.ViewModel.DoSave(this.Images, this.DeletedImages);
                ClearFields();
            }
            finally
            {
                RegistryInfo.Images.Remove(this.ClientID);
                this.DeletedImages = null;
            }
        }

        /// <summary>
        /// Gets or sets the extra label.
        /// </summary>
        /// <value>
        /// The extra label.
        /// </value>
        public string ExtraLabel
        {
            get
            {
                return this.txtPhotoLabels.Text;
            }
            set
            {
                this.txtPhotoLabels.Text = value;
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether this <see cref="InsertAttchments"/> is disabled.
        /// </summary>
        /// <value>
        ///   <c>true</c> if disabled; otherwise, <c>false</c>.
        /// </value>
        public bool Disabled
        {
            get
            {
                return fuImage.Disabled;
            }
            set
            {
                fuImage.Disabled = value;
                cmbType.Disabled = value;
                txtPhotoLabels.Disabled = value;
                btnDelete.Disabled = value;
                btnUpload.Disabled = value;
            }
        }

        #endregion
    }
}